package org.linlinjava.litemall.admin.service.marketing_manage;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.linlinjava.litemall.admin.enums.AdminErrorCode;
import org.linlinjava.litemall.admin.vo.marketing_manage.*;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.dao.*;
import org.linlinjava.litemall.db.dao.marketing_manage.MarketingDeductionMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.marketing_manage.AgedmallMarketingDeductionService;
import org.linlinjava.litemall.db.vo.marketing_manager.*;
import org.linlinjava.litemall.db.vo.shop.StoreGoodsInventoryDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author houzb
 * @Description
 * @create 2021-08-28 14:57
 */
@Service
public class MarketingDeductionService {
    @Resource
    private MarketingDeductionMapper marketingDeductionMapper;
    @Resource
    private AgedmallDeductionRuleMapper agedmallDeductionRuleMapper;
    @Resource
    private AgedmallMarketingDeductionService agedmallMarketingDeductionService;
    @Resource
    private LitemallGoodsMapper litemallGoodsMapper;
    @Resource
    private AgedmallStoreMapper agedmallStoreMapper;
    @Resource
    private AgedmallStoreGoodsMapper agedmallStoreGoodsMapper;
    @Resource
    private AgedmallDeductDetailMapper agedmallDeductDetailMapper;


    public List<MarketingDeductionRuleInfo> list(Map<String, Object> params) {
        Object offsetObj = params.get("offset");
        Object limitObj = params.get("limit");
        if (offsetObj != null && limitObj != null) {
            PageHelper.startPage(Integer.parseInt(offsetObj.toString()), Integer.parseInt(limitObj.toString()));
        }
        return marketingDeductionMapper.deductionList(params);
    }

    public int count(Map<String, Object> params) {
        return marketingDeductionMapper.count(params);
    }

    public int saveRule(AgedmallDeductionRule record) {
        return agedmallDeductionRuleMapper.insert(record);
    }

    /**
     * 获取抵扣金统计的数据信息
     *
     * @param params
     * @return
     */
    public DeductionStaticDataInfo getDeductionStaticData(Map<String, Object> params) {
        return agedmallMarketingDeductionService.getMarketingDeductionStaticDataInfo(params);
    }

    /**
     * 根据id下架抵扣金规则
     *
     * @param id
     * @return
     */
    public int offlineDeductionRuleConfRule(long id) {
        AgedmallDeductionRule rule = new AgedmallDeductionRule();
        rule.setId(id);
        rule.setStat(DeductionRuleStatEnum.OFF_SHELF.getStatVal());
        return agedmallDeductionRuleMapper.updateByPrimaryKey(rule);
    }


    public Object addRule(AddRuleVo addRuleVo) {
        AgedmallDeductionRuleExample ruleExample = new AgedmallDeductionRuleExample();
        ruleExample.or().andNameEqualTo(addRuleVo.getName()).andDeletedEqualTo(false);
        AgedmallDeductionRule agedmallDeductionRule = agedmallDeductionRuleMapper.selectOneByExample(ruleExample);
        if (ObjectUtil.isNotNull(agedmallDeductionRule)) {
            return ResponseUtil.fail(AdminErrorCode.RULE_NAME_IS_EXIST.getCode(), AdminErrorCode.RULE_NAME_IS_EXIST.getMessage());
        } else {
            agedmallDeductionRule = new AgedmallDeductionRule();
        }
        agedmallDeductionRule.setName(addRuleVo.getName());
        agedmallDeductionRule.setMoneyType(addRuleVo.getRuleMethod());
        agedmallDeductionRule.setMoney(addRuleVo.getRuleValue());
        agedmallDeductionRule.setType(addRuleVo.getType());
        agedmallDeductionRule.setStartTime(DateUtil.parseLocalDateTime(addRuleVo.getTimes().get(0)));
        agedmallDeductionRule.setEndTime(DateUtil.parseLocalDateTime(addRuleVo.getTimes().get(1)));
        agedmallDeductionRule.setCanCustomGoodsType(addRuleVo.getGoodsType());
        agedmallDeductionRule.setCanCustomGoods(addRuleVo.getGoodsList().size() > 0 ? StringUtils.join(addRuleVo.getGoodsList(), ",") : null);
        agedmallDeductionRule.setCanCustomStoreType(addRuleVo.getStoreType());
        agedmallDeductionRule.setCanCustomStore(addRuleVo.getStoreList().size() > 0 ? StringUtils.join(addRuleVo.getStoreList(), ",") : null);
        agedmallDeductionRule.setBusId(addRuleVo.getBusiId().longValue());
        agedmallDeductionRule.setStat(0);
        agedmallDeductionRule.setAddTime(LocalDateTime.now());
        agedmallDeductionRule.setLastOnlineTime(LocalDateTime.now());
        agedmallDeductionRuleMapper.insertSelective(agedmallDeductionRule);
        return ResponseUtil.ok();
    }


    public Object editRule(AddRuleVo addRuleVo) {
        AgedmallDeductionRule agedmallDeductionRule = agedmallDeductionRuleMapper.selectByPrimaryKey(addRuleVo.getId().longValue());
        AgedmallDeductionRuleExample ruleExample = new AgedmallDeductionRuleExample();
        ruleExample.or().andNameEqualTo(addRuleVo.getName()).andDeletedEqualTo(false);
        AgedmallDeductionRule isExistRule = agedmallDeductionRuleMapper.selectOneByExample(ruleExample);
        if (ObjectUtil.isNotNull(isExistRule) && !agedmallDeductionRule.getName().equals(addRuleVo.getName())) {
            return ResponseUtil.fail(AdminErrorCode.RULE_NAME_IS_EXIST.getCode(), AdminErrorCode.RULE_NAME_IS_EXIST.getMessage());
        }
        agedmallDeductionRule.setName(addRuleVo.getName());
        agedmallDeductionRule.setMoneyType(addRuleVo.getRuleMethod());
        agedmallDeductionRule.setMoney(addRuleVo.getRuleValue());
        agedmallDeductionRule.setType(addRuleVo.getType());
        agedmallDeductionRule.setStartTime(DateUtil.parseLocalDateTime(addRuleVo.getTimes().get(0)));
        agedmallDeductionRule.setEndTime(DateUtil.parseLocalDateTime(addRuleVo.getTimes().get(1)));
        agedmallDeductionRule.setCanCustomGoodsType(addRuleVo.getGoodsType());
        agedmallDeductionRule.setCanCustomGoods(addRuleVo.getGoodsList().size() > 0 ? StringUtils.join(addRuleVo.getGoodsList(), ",") : null);
        agedmallDeductionRule.setCanCustomStoreType(addRuleVo.getStoreType());
        agedmallDeductionRule.setCanCustomStore(addRuleVo.getStoreList().size() > 0 ? StringUtils.join(addRuleVo.getStoreList(), ",") : null);
        agedmallDeductionRuleMapper.updateByPrimaryKey(agedmallDeductionRule);
        return ResponseUtil.ok();
    }


    public Object deleteRule(List<Long> idList) {
        AgedmallDeductionRuleExample deductionRuleExample = new AgedmallDeductionRuleExample();
        deductionRuleExample.or().andIdIn(idList);
        agedmallDeductionRuleMapper.logicalDeleteByExample(deductionRuleExample);
        return ResponseUtil.ok();
    }

    public Object detailRule(DetailRuleVo detailRuleVo) {
        AgedmallDeductionRule agedmallDeductionRule = agedmallDeductionRuleMapper.selectByPrimaryKey(detailRuleVo.getId());
        DetailRuleBack detailRuleBack = new DetailRuleBack(agedmallDeductionRule);

        List<Long> allGoodsId = new ArrayList<>();
        if (detailRuleBack.getGoodsType() == 1) {
            LitemallGoodsExample goodsExample = new LitemallGoodsExample();
            goodsExample.or().andBusIdEqualTo(agedmallDeductionRule.getBusId().intValue());
            List<LitemallGoods> allGoods = litemallGoodsMapper.selectByExample(goodsExample);
            List<RuleGoods> ruleGoods = new ArrayList<>();
            allGoods.forEach(goods -> {
                allGoodsId.add(goods.getId().longValue());
                ruleGoods.add(new RuleGoods(goods));
            });
            detailRuleBack.setGoodsList(ruleGoods);
        } else if (detailRuleBack.getGoodsType() == 0) {
            String[] chooseGoods = agedmallDeductionRule.getCanCustomGoods().split(",");
            ArrayList<Integer> arrayList = new ArrayList<>(chooseGoods.length);
            for (int j = 0; j < chooseGoods.length; j++) {
                arrayList.add(Integer.parseInt(chooseGoods[j]));
                allGoodsId.add(Long.parseLong(chooseGoods[j]));
            }
            LitemallGoodsExample goodsExample = new LitemallGoodsExample();
            goodsExample.or().andIdIn(arrayList);
            List<LitemallGoods> chooseGoodsList = litemallGoodsMapper.selectByExample(goodsExample);
            List<RuleGoods> ruleGoods = new ArrayList<>();
            chooseGoodsList.forEach(goods -> {
                ruleGoods.add(new RuleGoods(goods));
            });
            detailRuleBack.setGoodsList(ruleGoods);
        }
        //部分
        if (detailRuleBack.getStoreType() == 0) {
            String[] chooseStores = agedmallDeductionRule.getCanCustomStore().split(",");
            ArrayList<Long> arrayList = new ArrayList<>(chooseStores.length);
            for (int j = 0; j < chooseStores.length; j++) {
                arrayList.add(Long.parseLong(chooseStores[j]));
            }
            AgedmallStoreExample agedmallStoreExample = new AgedmallStoreExample();
            agedmallStoreExample.or().andIdIn(arrayList);
            List<AgedmallStore> beChooseStores = agedmallStoreMapper.selectByExample(agedmallStoreExample);
            List<RuleStore> ruleStores = new ArrayList<>();
            beChooseStores.forEach(stores -> {
                ruleStores.add(new RuleStore(stores));
            });
            detailRuleBack.setStoreList(ruleStores);
        }
        //选中不支持
        else if (detailRuleBack.getStoreType() == 1) {
            String[] chooseStores = agedmallDeductionRule.getCanCustomStore().split(",");
            ArrayList<Long> arrayList = new ArrayList<>(chooseStores.length);
            for (int j = 0; j < chooseStores.length; j++) {
                arrayList.add(Long.parseLong(chooseStores[j]));
            }
            AgedmallStoreExample agedmallStoreExample = new AgedmallStoreExample();
            agedmallStoreExample.or().andIdIn(arrayList);
            List<AgedmallStore> beChooseStores = agedmallStoreMapper.selectByExample(agedmallStoreExample);
            List<RuleStore> ruleStores = new ArrayList<>();
            beChooseStores.forEach(stores -> {
                ruleStores.add(new RuleStore(stores));
            });
            detailRuleBack.setStoreList(ruleStores);
        }
        //全部
        else if (detailRuleBack.getStoreType() == 2) {
            AgedmallStoreGoodsExample storeGoodsExample = new AgedmallStoreGoodsExample();
            storeGoodsExample.or().andDeletedEqualTo(false).andGoodsIdIn(allGoodsId);
            List<AgedmallStoreGoods> agedmallStoreGoods = agedmallStoreGoodsMapper.selectByExample(storeGoodsExample);
            List<Long> storeList = new ArrayList<>();
            agedmallStoreGoods.forEach(storeGoods -> storeList.add(storeGoods.getStoreId()));
            AgedmallStoreExample agedmallStoreExample = new AgedmallStoreExample();
            agedmallStoreExample.or().andBusiIdEqualTo(agedmallDeductionRule.getBusId().intValue()).andIdIn(storeList);
            List<AgedmallStore> allStore = agedmallStoreMapper.selectByExample(agedmallStoreExample);
            List<RuleStore> ruleStores = new ArrayList<>();
            allStore.forEach(stores -> {
                ruleStores.add(new RuleStore(stores));
            });
            detailRuleBack.setStoreList(ruleStores);
        }


        return ResponseUtil.ok();
    }


    public Object changeState(ChangeStateVo changeStateVo) {
        AgedmallDeductionRuleExample ruleExample = new AgedmallDeductionRuleExample();
        ruleExample.or().andIdIn(changeStateVo.getIdList());
        AgedmallDeductionRule deductionRule = new AgedmallDeductionRule();
        deductionRule.setStat(changeStateVo.getType());
        if (changeStateVo.getType() == 0) {
            deductionRule.setLastOnlineTime(LocalDateTime.now());
        }
        agedmallDeductionRuleMapper.updateByExample(deductionRule, ruleExample);
        return ResponseUtil.ok();
    }


    public Object ruleList(RuleListVo ruleListVo) {
        Page page = PageHelper.startPage(ruleListVo.getPage(), ruleListVo.getLimit());
        List<DeductionListBackDto> ruleList = marketingDeductionMapper.getRuleList(ruleListVo.getType(), ruleListVo.getState(),
                ruleListVo.getName(), ruleListVo.getBusiId());
        Map<String, Object> map = new HashMap<>();
        map.put("total", page.getTotal());
        map.put("data", ruleList);
        return ResponseUtil.ok(map);
    }

    public Object summary(Integer userId, Integer busiId) {
        AgedmallDeductDetailExample deductDetailExample = new AgedmallDeductDetailExample();
        deductDetailExample.or().andUserIdEqualTo(userId).andBusiIdEqualTo(busiId).andDeletedEqualTo(false);
        List<AgedmallDeductDetail> agedmallDeductDetails = agedmallDeductDetailMapper.selectByExample(deductDetailExample);

        //可用抵扣金
        Long couldUse = 0L;
        //累计发放抵扣金
        Long mcumulativeDis = 0L;
        //累计消耗抵扣金
        Long cumulativeUse = 0L;
        //根据消耗  获取分组
        Map<String, List<AgedmallDeductDetail>> deductDetailByType = agedmallDeductDetails.stream().collect(Collectors.groupingBy(AgedmallDeductDetail::getType));
        for (Map.Entry<String, List<AgedmallDeductDetail>> entry : deductDetailByType.entrySet()) {
            String mapKey = entry.getKey();
            List<AgedmallDeductDetail> mapValue = entry.getValue();
            for (AgedmallDeductDetail deduct : mapValue) {
                if (mapKey.equals("GET")) {
                    mcumulativeDis += deduct.getDeductNumber();
                } else {
                    cumulativeUse += deduct.getDeductNumber();
                }
            }
        }
        couldUse = mcumulativeDis - cumulativeUse;
        Map<String, Object> map = new HashMap<>();
        //可用抵扣金
        map.put("couldUseTotal", couldUse);
        //累计发放抵扣金
        map.put("cumulativeDisTotal", mcumulativeDis);
        //累计消耗抵扣金
        map.put("cumulativeUseTotal", cumulativeUse);
        return ResponseUtil.ok(map);
    }


    public Object ruleUserStatic(RuleUserStaticVo ruleUserStaticVo) {
        Page page = PageHelper.startPage(ruleUserStaticVo.getPage(), ruleUserStaticVo.getLimit());
        LocalDateTime startTime = StrUtil.isNotBlank(ruleUserStaticVo.getStartTime()) ? DateUtil.parseLocalDateTime(ruleUserStaticVo.getStartTime()) : null;
        LocalDateTime endTime = StrUtil.isNotBlank(ruleUserStaticVo.getEndTime()) ? DateUtil.parseLocalDateTime(ruleUserStaticVo.getEndTime()) : null;
        List<DeductionUserListDto> deductionUserListDtos = marketingDeductionMapper.selectDeductionUserList(ruleUserStaticVo.getBusiId(),
                ruleUserStaticVo.getId(), ruleUserStaticVo.getType(), ruleUserStaticVo.getPhone(), ruleUserStaticVo.getStoreId(),
                ruleUserStaticVo.getGoodsId(), startTime, endTime);
        //根据用户id分组
        Map<Integer, List<DeductionUserListDto>> deductDetailById = deductionUserListDtos.stream().collect(Collectors.groupingBy(DeductionUserListDto::getUserId));

        //可用抵扣金
        Long couldUse = 0L;
        //累计发放抵扣金
        Long mcumulativeDis = 0L;
        //累计消耗抵扣金
        Long cumulativeUse = 0L;
        List<DeductionUserListDto> userBackList = new ArrayList<>();
        for (Map.Entry<Integer, List<DeductionUserListDto>> entry : deductDetailById.entrySet()) {
            List<DeductionUserListDto> mapValue = entry.getValue();
            if (!mapValue.isEmpty()) {
                DeductionUserListDto deductionUserListDto = new DeductionUserListDto();
                deductionUserListDto.setUserId(entry.getKey());
                deductionUserListDto.setNickname(mapValue.get(0).getNickname());
                deductionUserListDto.setMobile(mapValue.get(0).getMobile());

                for (int i = 0; i < mapValue.size(); i++) {
                    DeductionUserListDto deductCount = mapValue.get(i);
                    if (deductCount.getType().equals("GET")) {
                        deductionUserListDto.setGetNumber(deductCount.getGetNumber());
                        mcumulativeDis += deductCount.getGetNumber();
                    } else {
                        deductionUserListDto.setUseNumber(deductCount.getUseNumber());
                        cumulativeUse += deductCount.getUseNumber();
                    }
                }
                deductionUserListDto.setCanUseNumber(deductionUserListDto.getGetNumber()-deductionUserListDto.getUseNumber());
                userBackList.add(deductionUserListDto);
            }
        }
        couldUse=mcumulativeDis-cumulativeUse;
        Map<String, Object> map = new HashMap<>();
        map.put("total", page.getTotal());
        map.put("data", userBackList);
        //可用抵扣金
        map.put("couldUseTotal", couldUse);
        //累计发放抵扣金
        map.put("cumulativeDisTotal", mcumulativeDis);
        //累计消耗抵扣金
        map.put("cumulativeUseTotal", cumulativeUse);
        return ResponseUtil.ok(map);
    }


    public Object ruleUserStaticOrderList(RuleUserStaticOrderListVo ruleUserStaticVo){
        LocalDateTime startTime = StrUtil.isNotBlank(ruleUserStaticVo.getStartTime()) ? DateUtil.parseLocalDateTime(ruleUserStaticVo.getStartTime()) : null;
        LocalDateTime endTime = StrUtil.isNotBlank(ruleUserStaticVo.getEndTime()) ? DateUtil.parseLocalDateTime(ruleUserStaticVo.getEndTime()) : null;
        Page page = PageHelper.startPage(ruleUserStaticVo.getPage(), ruleUserStaticVo.getLimit());
        List<DeductionOrderListDto> deductionOrderListDtos = marketingDeductionMapper.selectDeductionOrderList(ruleUserStaticVo.getUserId(), ruleUserStaticVo.getBusiId(), ruleUserStaticVo.getId(),
                ruleUserStaticVo.getType(), ruleUserStaticVo.getOrderSn(), ruleUserStaticVo.getGoodsId(), startTime, endTime);

        Map<String, Object> map = new HashMap<>();
        map.put("total", page.getTotal());
        map.put("data", deductionOrderListDtos);
        return ResponseUtil.ok(map);
    }

}
